package org.aspose;

import com.aspose.words.Font;
import com.aspose.words.Shape;
import com.aspose.words.*;

import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.function.Function;

/**
 * 操作word 文档
 *
 * @author lixing
 * @version V1.0
 * @ClassName:
 * @Description:
 * @Date 2024/8/19 16:09
 */
public class ManipulateWord {

    public static void main(String[] args) throws Exception {
        // createTable("C:\\Users\\XingL\\Desktop\\aaa.docx", "C:\\Users\\XingL\\Desktop\\aaa2.docx");
        Document doc = new Document("C:\\Users\\XingL\\Desktop\\xxx.docx");
        // Document doc = new Document("C:\\Users\\XingL\\Desktop\\_basefs_tmp.docx");
        DocumentBuilder builder = new DocumentBuilder(doc);

        doc.getRange().replace("START_DEPT_NAME", "综合部");
        doc.getRange().replace("DUTYNAME", "二级副职经理");
        doc.getRange().replace("NOW_YEAR", "2024");

        doc.getRange().replace("START_YEAR", "2024");
        doc.getRange().replace("END_YEAR", "2024");
        doc.getRange().replace("NUMBERBING", "Y0183719383");

        NodeCollection childNodes = doc.getChildNodes(NodeType.PARAGRAPH, true);
        for (Paragraph paragraph : (Iterable<Paragraph>) childNodes) {
            if (paragraph.getText().contains("TEXT_CONTENT")) {
                paragraph.getRange().replace("TEXT_CONTENT", "");
                builder.moveTo(paragraph);
                for (int i = 0; i < 2; i++) {
                    // 标题
                    builder.getFont().setName("宋体");// 字体
                    builder.getFont().setBold(true);// 加粗
                    builder.getParagraphFormat().getStyle().getFont().setSize(16);// 字体大小
//                    builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1);//标题样式
                    builder.getParagraphFormat().setAlignment(ParagraphAlignment.JUSTIFY);// 两端对齐
                    builder.getParagraphFormat().setLineSpacingRule(LineSpacingRule.MULTIPLE);// 多倍行距
                    builder.getParagraphFormat().setLineSpacing(18);// 1.5倍行距
                    builder.getParagraphFormat().setFirstLineIndent(0);
                    builder.writeln("第一条  经营业绩考核");
                    // 内容
                    builder.getFont().setName("宋体");
                    builder.getFont().setBold(false);
                    builder.getParagraphFormat().getStyle().getFont().setSize(12);
                    builder.getParagraphFormat().setFirstLineIndent(20);
                    builder.writeln("为贯彻落实集团公司创世界一流“力量大厦”战略部署，确保集团公司经营业绩目标的达成，建立责、权、利匹配的经理层成员任期制和契约化管理体系，激发企业内生活力动力，中国移动通信集团北京有限公司（以下简称“北京公司”）现与中国移动通信集团北京有限公司xx部门总经理（以下简称“xx部门总经理”）签订2023年度经营业绩责任书，并开展2023年度经营业绩考核。");
                }
                break;
            }
        }
        // 创建表格
        builder.startTable();
        builder.getCellFormat().getBorders().setLineStyle(LineStyle.SINGLE);
        builder.getCellFormat().getBorders().setColor(Color.BLACK);

        builder.getCellFormat().setWidth(120);// 固定宽度
        builder.getCellFormat().setFitText(false);// 设置自适应关闭
        builder.getCellFormat().setWrapText(true);// 设置自动换行

        List<String> colsList = Arrays.asList("考核指标", "分值", "考核目标", "是否主要指标");
        int numCols = 4;// 列
        int numRows = 2;// 行

        for (int row = 0; row < numRows; row++) {
            if (row == 0) {
                for (String col : colsList) {
                    builder.insertCell();
                    builder.writeln(col);
                }
            } else {
                for (int col = 0; col < numCols; col++) {
                    builder.insertCell();
                    switch (col) {
                        case 0:
                            builder.writeln("templateAssess.getAssessmentIndicator()");
                            break;
                        case 1:
                            builder.writeln("templateAssess.getScore()".toString());
                            break;
                        case 2:
                            builder.writeln("templateAssess.getAssessmentPoints()");
                            break;
                        case 3:
                            builder.writeln("templateAssess.getPrimaryIndicator()");
                            break;
                        default:
                            builder.writeln("");
                            break;
                    }
                }
            }
            // 结束当前行
            builder.endRow();
        }
        builder.endTable();
/**********************************************************************************/
        // setFindReplace(doc, builder, "START_DEPT_NAME", "综合部");
        // setFindReplace(doc, builder, "DUTYNAME", "二级副职经理");
        // setFindReplace(doc, builder, "NOW_YEAR", "2024");
        //
        // //
        // setFindReplace(doc, builder, "START_YEAR", "2024");
        // setFindReplace(doc, builder, "END_YEAR", "2024");
        //
        // // setFindReplace(doc, builder, "TEXT_CONTENT", "测试内容");
        // setFindReplace(doc, builder, "NUMBERBING", "2024-Y0183719383");
        // setFindReplace(doc, builder, "END_DEPT_NAME", "综合部");
        //
        //
        // setFindReplace3(doc, builder, "TEXT_CONTENT", Arrays.asList("测试杀杀杀杀杀杀杀杀杀", "发发哇达瓦达瓦法网发蛙发我", "啊烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦", "测试杀杀杀杀杀杀杀杀杀", "发发哇达瓦达瓦法网发蛙发我", "啊烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦", "测试杀杀杀杀杀杀杀杀杀", "发发哇达瓦达瓦法网发蛙发我", "啊烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦烦"));
        doc.save("C:\\Users\\XingL\\Desktop\\xxx.pdf", SaveFormat.PDF);
        // convertWordToPdf("C:\\Users\\XingL\\Desktop\\xxx.docx", "C:\\Users\\XingL\\Desktop\\xxx.pdf", null);
    }


    /**
     * 将Word文档转换为PDF格式
     *
     * @param inputPath  输入Word文件的路径
     * @param outputPath 输出PDF文件的路径
     * @param fontDir    字体目录的路径
     */
    public static void convertWordToPdf(String inputPath, String outputPath, String fontDir) {
        try {
            // 记录转换开始的时间
            long startTime = System.currentTimeMillis();
            // 加载Word文档
            Document doc = new Document(inputPath);

            // 创建字体设置
            FontSettings fontSettings = new FontSettings();
            // 设置字体目录
            fontSettings.setFontsSources(new FontSourceBase[]{new SystemFontSource(), new FolderFontSource(fontDir, true)});
            // 设置字体设置
            doc.setFontSettings(fontSettings);

            // 保存文档为PDF格式
            doc.save(outputPath, SaveFormat.PDF);
            // 记录转换结束的时间
            long endTime = System.currentTimeMillis();
            System.out.println("Word转换为PDF成功！" + (endTime - startTime));
        } catch (Exception e) {
        }
    }


    // 生成一个word 文档
    public static void createWord() throws Exception {
        // 通过Document空的构造函数，创建一个新的空的文档,如果有参数则是根据模板加载文档。
        Document doc = new Document("output/school_template.docx");
        // 动态增加内容 获取光标，这里面的`builder`相当于一个画笔，提前给他规定样式，然后他就能根据你的要求画出你想画的Word。
        // 这里的画笔使用的是就近原则，当上面没有定义了builder的时候，会使用默认的格式，当上面定义了某个格式的时候，使用最近的一个（即最后一个改变的样式）
        DocumentBuilder builder = new DocumentBuilder(doc);
        // 将光标移动到文档末端
        builder.moveToDocumentEnd();

        /*操作文档的一些可直接调用的方法*/
        // 换行 插入一个新的段落
        builder.insertParagraph();
        // 也是换行的意思
        builder.writeln();
        // 插入分页符（换页）
        builder.insertBreak(BreakType.PAGE_BREAK);
        // 光标移至文档开头
        builder.moveToDocumentStart();
        // 插入书签
        builder.startBookmark("MyBookmark");
        builder.writeln("This is the content inside the bookmark.");
        builder.endBookmark("MyBookmark");

        // 文件命名
        String fileName = "output/AsposeWord1" + new SimpleDateFormat("MMddHHmmss").format(new Date()) + ".docx";
        // 文件保存
        doc.save(fileName);
    }

    /**
     * 新建一个table表格
     *
     * @throws Exception
     */
    public static void createTable(String inputPath, String outputPath) throws Exception {
        // 创建一个Document对象
        Document doc = new Document(inputPath);
        // 创建一个DocumentBuilder对象
        DocumentBuilder builder = new DocumentBuilder(doc);

        // 开始创建一个 5 列 10 行的表格
        Table table = builder.startTable();
        builder.getCellFormat().getBorders().setLineStyle(LineStyle.SINGLE);
        builder.getCellFormat().getBorders().setColor(Color.BLACK);

        // 创建一个5列10行的表格
        int numCols = 5;  // 列数
        int numRows = 10; // 行数

        builder.getCellFormat().setWidth(30); // 固定宽度
        builder.getCellFormat().setFitText(false);// 设置自适应关闭
        builder.getCellFormat().setWrapText(true);// 设置自动换行

        for (int row = 0; row < numRows; row++) {
            for (int col = 0; col < numCols; col++) {
                builder.insertCell(); // 插入单元格
                builder.write("测试行  Row" + (row + 1) + ",测试列 Col " + (col + 1)); // 填充数据
            }
            // 插入换行
            // builder.writeln();
            builder.endRow(); // 结束当前行
        }

        // for (Row row : table.getRows()) {
        //     // table.getFirstRow().getCells().get(0).getCellFormat().setWidth(30);
        //     for (int i = 0; i < numCols; i++) {
        //         row.getCells().get(i).getCellFormat().setWidth(30);
        //         row.getCells().get(i).getCellFormat().setFitText(false);//设置自适应关闭
        //         row.getCells().get(i).getCellFormat().setWrapText(true);//设置自动换行
        //     }
        // }
        // builder.getRowFormat().setHeight(100);// 设置行高
        // builder.getRowFormat().setHeightRule(HeightRule.EXACTLY);// 设置行高规则

        // 结束表格
        builder.endTable();


        doc.save(outputPath);
    }

    /**
     * 创建列值
     *
     * @param value 要插入的值
     * @param doc   Document对象
     * @return
     */
    public static Cell CreateCell(String value, Document doc) {
        Cell cell = new Cell(doc);
        Paragraph p = new Paragraph(doc);
        p.appendChild(new Run(doc, value));
        cell.appendChild(p);
        return cell;
    }


    /*
     * @Description: 比较文档
     * */
    public static void cmpDocument(Document doc1, Document doc2) throws Exception {
        // 忽略一些内容格式,可以根据自己的实际需求调节。
        CompareOptions options = new CompareOptions();
        options.setIgnoreFormatting(true);
        options.setIgnoreHeadersAndFooters(true);
        options.setIgnoreCaseChanges(true);
        options.setIgnoreTables(true);
        options.setIgnoreFields(true);
        options.setIgnoreComments(true);
        options.setIgnoreTextboxes(true);
        options.setIgnoreFootnotes(true);
        // 涉及Microsoft Word“比较文档”对话框中的“显示更改”选项
        options.setTarget(ComparisonTargetType.NEW);
        doc1.compare(doc2, "user", new Date(), options);
        if (doc1.getRevisions().getCount() == 0) {
            System.out.println("Documents are equal");
        } else {
            System.out.println("Documents are not equal");
        }
    }

    /**
     * 无格式要求 文本查找替换
     *
     * @param doc
     * @param builder
     * @param searchText
     * @param replaceText
     * @throws Exception
     */
    public static void setFindReplace(Document doc, DocumentBuilder builder, String searchText, String replaceText) throws Exception {
        // 在整个文档范围内查找 searchText，并将其替换为 replaceText
        doc.getRange().replace(searchText, replaceText);
        // 将光标移到文档的末尾
        builder.moveToDocumentEnd();
    }

    /**
     * 有格式要求文本查找替换
     *
     * @param doc
     * @param builder
     * @param searchText
     * @param replaceText
     * @throws Exception
     */
    public static void setFindReplace2(Document doc, DocumentBuilder builder, String searchText, String replaceText) throws Exception {
        // 创建一个查找替换器
        FindReplaceOptions options = new FindReplaceOptions();
        // 遍历文档中的所有段落
        NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true);
        for (Paragraph paragraph : (Iterable<Paragraph>) paragraphs) {
            // 遍历段落中的所有运行节点
            NodeCollection runs = paragraph.getChildNodes(NodeType.RUN, true);
            for (Run run : (Iterable<Run>) runs) {
                // 判断文本是否包含要替换的文本
                if (run.getText().contains(searchText)) {
                    // 获取当前运行节点的字体
                    Font font = run.getFont();
                    // 设置要替换的文本的字体格式
                    font.setName("华文仿宋");
                    font.setSize(20);
                    // 设置替换文本的颜色为红色
                    font.setColor(new Color(199, 42, 60));
                    // 是否加粗
                    font.setBold(false);
                    // 设置居中对齐
                    paragraph.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER);
                    // 设置下划线样式
                    // font.setUnderline(Underline.SINGLE);
                    // 设置下划线颜色
                    // font.setUnderlineColor(new Color(63,145,227));
                    // 保留元字符
                    // options.setPreserveMetaCharacters(true);
                    // 执行替换
                    run.setText(run.getText().replace(searchText, replaceText));
                }
            }
        }
        // 将光标移动到文档末
        builder.moveToDocumentEnd();
    }

    public static void LockLastThreePages(Document doc, int pageCount) {
        SectionCollection sections = doc.getSections();
        int count = sections.getCount();
        if (count >= pageCount) {
            Section section = sections.get(count - pageCount);
            pageCount--;
            // 锁定页面
            section.getPageSetup().setSectionStart(SectionStart.NEW_PAGE);// 新一页
            section.getPageSetup().setTopMargin(0);// 页面顶部边距
            section.getPageSetup().setBottomMargin(0);// 页面底部边距
            section.getPageSetup().setLeftMargin(0);// 页面左边距
            section.getPageSetup().setRightMargin(0);// 页面右边距
            section.getPageSetup().setRestartPageNumbering(true);// 重新开始页码
            // section.getPageSetup().setDifferentFirstPageHeaderFooter(true);// 奇偶页不同
            // section.getPageSetup().setOddAndEvenPagesHeaderFooter(true);// 奇偶页相同
            // section.getPageSetup().setHeaderDistance(0);// 页眉距离顶部的距离
            // section.getPageSetup().setFirstPageTray(1);// 第一页纸张
            // section.getPageSetup().setOtherPagesTray(1);// 其他页纸
            // section.getPageSetup().setPaperSize(PaperSize.A4);// 设置纸张大小
        }
    }

    public static void setFindReplace3(Document doc, DocumentBuilder builder, String searchText, List<String> replaceText) throws Exception {
        // replaceText.removeIf(filter -> filter.contains("xxx"));
        // 移动 DocumentBuilder 到占位符位置
        // builder.moveToDocumentStart(); // 起始位置
        // builder.getDocument().getRange().replace(searchText, "", new FindReplaceOptions(FindReplaceDirection.FORWARD));// 指定搜索的方向
        // LockLastThreePages(doc,3);
        // 遍历文档中的所有段落
        NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true);
        // 遍历段落
        for (Paragraph paragraph : (Iterable<Paragraph>) paragraphs) {
            // 判断段落是否包含要替换的文本
            if (paragraph.getText().contains(searchText)) {
                // paragraph.removeAllChildren();
                paragraph.getRange().replace(searchText, "");
                builder.moveTo(paragraph);
                for (String replace : replaceText) {
                    // 插入标题
                    builder.getFont().setName("宋体");// 字体
                    builder.getFont().setBold(true);// 加粗
                    builder.getParagraphFormat().getStyle().getFont().setSize(16); // 可以设置标题的字体大小
                    // builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); // 标题样式
                    builder.getParagraphFormat().setAlignment(ParagraphAlignment.JUSTIFY);// 段落对齐方式：两端对齐
                    builder.getParagraphFormat().setLineSpacingRule(LineSpacingRule.MULTIPLE);// 设置段落格式的行间距规则为多倍行距
                    builder.getParagraphFormat().setLineSpacing(18);// 设置行距为1.5倍
                    builder.getParagraphFormat().setFirstLineIndent(0);
                    builder.writeln("content.Title");

                    // 插入内容
                    builder.getFont().setBold(false);
                    builder.getParagraphFormat().getStyle().getFont().setSize(12); // 内容的字体大小
                    builder.getParagraphFormat().setFirstLineIndent(20);// 设置首行缩进
                    builder.writeln(replace);

                    // Executors.newFixedThreadPool()
                    // 添加标题
                    // Run titleRun = new Run(doc, "标题");
                    // titleRun.getFont().setBold(true);
                    // titleRun.getFont().setSize(16); // 可以设置标题的字体大小
                    // paragraph.appendChild(titleRun);

                    // 添加内容
                    // Run bodyRun = new Run(doc, replace);
                    // bodyRun.getFont().setBold(false);
                    // bodyRun.getFont().setSize(12); // 内容的字体大小
                    // paragraph.appendChild(bodyRun);

                    // 添加换行符
                    // builder.insertBreak(BreakType.LINE_BREAK);
                    // paragraph.appendChild(new Run(doc, "\n"));
                }
                break;
            }
        }
    }

    /**
     * @Description: 设置页面布局
     */
    public static void setPages(DocumentBuilder builder, Document doc) throws Exception {
        // 将页面设置重置为默认纸张大小、边距和方向。
        builder.getPageSetup().clearFormatting();
        // 指定页面边框是包含还是不包含页脚。
        builder.getPageSetup().setBorderSurroundsFooter(true);
        // 指定页面边框是包含还是不包含页眉。
        builder.getPageSetup().setBorderSurroundsHeader(true);
        // 设置纸张布局,将纸张布局调整为A4
        builder.getPageSetup().setPaperSize(PaperSize.A4);
        // 设置了表格行的边框线条样式为THICK，即较粗的线条
        // builder.getRowFormat().getBorders().setLineStyle(LineStyle.THICK);
        // 这一行代码设置了表格行的高度规则为AUTO
        // builder.getRowFormat().setHeightRule(HeightRule.AUTO);
        // 设置行间距: 1.0等于12点,1.5行=18点,1.3倍行间距=15点
        builder.getParagraphFormat().setLineSpacing(15);// 设置行间距
        // getPageSetup(): 这是获取页面设置的方法，通过该方法你可以获得页面设置对象，进而设置页面的各种属性。
        // 设置页面左边缘和正文左边界之间的距离（以磅为单位）。
        doc.getFirstSection().getPageSetup().setLeftMargin(72.0);
        // 设置页面右边缘与正文右边界之间的距离（以磅为单位）。
        doc.getFirstSection().getPageSetup().setRightMargin(72.0);
        // 设置页面上边缘与正文上边界之间的距离（以磅为单位）。
        doc.getFirstSection().getPageSetup().setTopMargin(72.0);
        // 设置页面底部边缘与正文底部边界之间的距离（以磅为单位）。
        doc.getFirstSection().getPageSetup().setBottomMargin(80.0);
    }

    /**
     * 区分各级标题
     */
    public static void setParagraphTitle(DocumentBuilder builder, Document doc, String title, Integer level) {
        try {
            switch (level) {
                case 1:
                    setTitle1(builder, title);
                    break;
                case 2:
                    setTitle2(builder, title);
                    break;
                case 3:
                    setTitle3(builder, title);
                    break;
                // setText4,设置特殊标题,形状标题
                case 4:
                    setTitle4(builder, doc, title);
                    break;
                default:
                    break;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 设置段落标 一二三级。
     * writeln 为每次会换行 write每次不换行
     */
    public static void setTitle1(DocumentBuilder builder, String title) throws Exception {
        builder.getFont().setName("仿宋"); // 字体
        builder.getFont().setColor(new Color(0, 0, 0)); // 字体颜色
        builder.getFont().setSize(16); // 三号字体 16号字大小
        builder.getFont().setBold(true); // 标题加粗撒旦
        builder.getParagraphFormat().setFirstLineIndent(0); // 首字不缩进
        builder.getParagraphFormat().setAlignment(ParagraphAlignment.LEFT); // 水平居中对齐; //左对齐
        builder.writeln(title);
    }

    public static void setTitle2(DocumentBuilder builder, String title) throws Exception {
        builder.getFont().setName("仿宋"); // 字体
        builder.getFont().setColor(new Color(0, 0, 0)); // 字体颜色
        builder.getFont().setSize(14); // 字体大小
        builder.getFont().setBold(true); // 标题加粗
        builder.getParagraphFormat().setFirstLineIndent(0); // 首字不缩进
        builder.getParagraphFormat().setAlignment(ParagraphAlignment.LEFT); // 水平居中对齐; //左对齐
        builder.writeln(title);
    }

    public static void setTitle3(DocumentBuilder builder, String title) throws Exception {
        builder.getFont().setName("仿宋"); // 字体
        builder.getFont().setColor(new Color(0, 0, 0)); // 字体颜色
        builder.getFont().setSize(10); // 字体大小
        builder.getFont().setBold(true); // 标题加粗
        builder.getParagraphFormat().setFirstLineIndent(0); // 首字不缩进
        builder.getParagraphFormat().setAlignment(ParagraphAlignment.LEFT); // 水平居中对齐; //左对齐
        builder.writeln(title);
    }

    /**
     * 设置段落标题,并且区分
     *
     * @param builder
     * @param doc
     * @param title
     * @throws Exception
     */
    public static void setTitle4(DocumentBuilder builder, Document doc, String title) throws Exception {
        Shape shape = builder.insertShape(ShapeType.DIAGONAL_CORNERS_SNIPPED, 450, 37);
        // 旋转
        shape.setRotation(0);
        // 形状边框颜色
        shape.setStrokeColor(new Color(95, 140, 195));
        // 形状体颜色
        shape.setFillColor(new Color(222, 235, 247));
        // 在形状中插入文字
        Paragraph para = new Paragraph(doc);
        Run run = new Run(doc);
        run.setText(title);
        run.getFont().setName("仿宋");
        run.getFont().setSize(16); // 三号字体 点数为16
        run.getFont().setColor(new Color(79, 128, 208));
        run.getFont().setBold(true); // 标题加粗
        para.getParagraphFormat().setFirstLineIndent(0); // 首字不缩进
        para.getParagraphFormat().setSpaceAfter(0.8);
        para.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER);
        para.appendChild(run);
        shape.appendChild(para);
    }

    /**
     * @Description: 使用HTML 设置文本及格式
     */
    public static void setText(DocumentBuilder builder, Object pragraph) throws Exception {
        builder.insertHtml("<p><font face='宋体'>&nbsp;&nbsp; " + pragraph + "</font></p>"); // 设置字体格式
    }

    public static void setParagraph1(DocumentBuilder builder, Object pragraph) throws Exception {
        builder.insertHtml("<p></p><font face='宋体' style = 'font-size:14px;'>&nbsp;&nbsp; " + pragraph + "</font>");
    }

    public static void setParagraph2(DocumentBuilder builder, Object pragraph) throws Exception {
        builder.insertHtml("<font face='宋体'style = 'font-size:14px;'>" + pragraph + "</font>"); // 设置字体格式
    }

    public static void setParagraph3(DocumentBuilder builder, Object pragraph) throws Exception {
        builder.insertHtml("<font face='宋体' style = 'font-size:14px; color:RED'>" + pragraph + "</font>"); // 设置字体格式
    }


    /**
     * 加文字水印方法
     *
     * @param doc           word文件流
     * @param watermarkText 水印内容
     */
    public static void insertWatermarkText(Document doc, String watermarkText) {
        // 居中
        insertWatermarkText(doc, watermarkText, new Function<Shape, Object>() {
            @Override
            public Object apply(Shape watermark) {
                // Place the watermark in the page center.
                watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
                watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
                watermark.setWrapType(WrapType.NONE);
                watermark.setVerticalAlignment(VerticalAlignment.CENTER);
                watermark.setHorizontalAlignment(HorizontalAlignment.CENTER);
                return null;
            }
        });
        // 顶部
        insertWatermarkText(doc, watermarkText, new Function<Shape, Object>() {
            @Override
            public Object apply(Shape watermark) {
                watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.MARGIN);
                watermark.setRelativeVerticalPosition(RelativeVerticalPosition.MARGIN);
                watermark.setWrapType(WrapType.NONE);
                //  我们需要自定义距离顶部的高度
                watermark.setVerticalAlignment(VerticalAlignment.TOP);
                watermark.setHorizontalAlignment(HorizontalAlignment.CENTER);
                //  watermark.setTop(120);
                return null;
            }
        });

        // 尾部
        insertWatermarkText(doc, watermarkText, new Function<Shape, Object>() {
            @Override
            public Object apply(Shape watermark) {
                watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.MARGIN);
                watermark.setRelativeVerticalPosition(RelativeVerticalPosition.MARGIN);
                watermark.setWrapType(WrapType.NONE);
                // 我们需要自定义距离顶部的高度
                watermark.setVerticalAlignment(VerticalAlignment.BOTTOM);
                watermark.setHorizontalAlignment(HorizontalAlignment.CENTER);
                // 设置距离顶部的高度
                //   watermark.setTop(480);

                return null;
            }
        });
    }


    /**
     * 插入文本水印
     */
    private static void insertWatermarkText(Document doc, String watermarkText, Function<Shape, Object> watermaskPositionConfigFunc) {

        Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT);
        watermark.getTextPath().setText(watermarkText);
        // 这里设置为宋体可以保证在转换为PDF时中文不是乱码.
        watermark.getTextPath().setFontFamily("WeiRuanYaHei");
        // WeiRuanYaHei 宋体

        try {
            // 水印大小
            watermark.setWidth(150);
            watermark.setHeight(30);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // 左下到右上
        watermark.setRotation(-20);
        // 字体RGB颜色
        final String colorStr = "EE8262";
        watermark.getFill().setColor(new java.awt.Color(Integer.parseInt(colorStr, 16)));
        watermark.setStrokeColor(new java.awt.Color(Integer.parseInt(colorStr, 16)));
        watermaskPositionConfigFunc.apply(watermark);
        Paragraph watermarkPara = new Paragraph(doc);
        watermarkPara.appendChild(watermark);
        for (Section sect : doc.getSections()) {
            // 插入水印
            insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);

        }

    }


    private static void insertWatermarkIntoHeader(Paragraph watermarkPara, Section sect, int headerType) {
        HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType);
        if (header == null) {
            header = new HeaderFooter(sect.getDocument(), headerType);
            sect.getHeadersFooters().add(header);
        }
        try {
            header.appendChild(watermarkPara.deepClone(true));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
